﻿using Mysoft.Map.Extensions.Web;
using Mysoft.Map.MVC;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using Mysoft.Map.Extensions.DAL;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using Mysoft.QuickCode.Office.Excel;
using System.IO;
using Mysoft.QuickCode.Web;
using Mysoft.QuickCode.Web.EasyUI;
using System.Reflection;
using Mysoft.QuickCode.DAL;
using Mysoft.QuickCode.Data.Validator;
using Mysoft.QuickCode.NPOI.SS.UserModel;
using Mysoft.QuickCode.NPOI.HSSF.UserModel;
using Mysoft.QuickCode.Office.Excel.Data;
using Mysoft.QuickCode.Common;

namespace Mysoft.QuickCode.Services
{
    /// <summary>
    /// 公共服务Ajax
    /// </summary>
    public class CommandService
    {
        HttpContext context = HttpContext.Current;

        /// <summary>
        /// 列表数据查询
        /// </summary>
        /// <returns></returns>
        [Action]
        public string List()
        {
            CommandObject sql = JsonConvert.DeserializeObject<CommandObject>(context.Request["Command"]);
            GridResult result = Grid.GetResult(SqlFile.GetContent(sql.File), sql.Order, null, false);
            return JsonConvert.SerializeObject(result.rows);
        }

        /// <summary>
        /// 通用列表查询通道
        /// </summary>
        /// <returns></returns>
        [Action]
        public string ListGrid()
        {
            CommandObject sql = JsonConvert.DeserializeObject<CommandObject>(context.Request["Command"]);
            GridResult result = Grid.GetResult(SqlFile.GetContent(sql.File), sql.Order, null, sql.Pageable);
            return JsonConvert.SerializeObject(result);
        }

        /// <summary>
        /// 纯执行SQL语句查询结果集JSON数据对象
        /// </summary>
        /// <returns></returns>
        [Action]
        public string ListTree()
        {
            List<object> list = new List<object>();
            CommandObject sql = JsonConvert.DeserializeObject<CommandObject>(context.Request["Command"]);
            List<TreeNode<object>> result = Grid.TreeList(SqlFile.GetContent(sql.File));
            return JsonConvert.SerializeObject(result);
        }

        /// <summary>
        /// 导出并返回导出文件地址
        /// </summary>
        /// <param name="excelFullName">要生成的Excel文件全地址和名称</param>
        /// <returns></returns>
        //[Action]
        //private string Export(string excelFullName)
        //{
        //    CommandObject sql = JsonConvert.DeserializeObject<CommandObject>(context.Request["Command"]);
        //    List<ExportField> fields = JsonConvert.DeserializeObject<List<ExportField>>(context.Request["ColumnsMapping"]); //导出字段的中英文映射
        //    List<KeyValuePair<string, string>> mappings = fields.Select(m => new KeyValuePair<string, string>(m.Field, m.Text)).ToList();
        //    GridResult result = Grid.GetResult(SqlFile.GetContent(sql.File), sql.Order);
        //    DataTable table = result.rows;  //即将导出的表格
        //    TableTool tt = new TableTool(table, string.Empty, mappings);

        //    excelFullName = string.IsNullOrEmpty(excelFullName)
        //        ? context.Request.ApplicationPath + "/tempfiles/" + DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(10000, 99999)
        //        : excelFullName;
        //    string excelPath = excelFullName; //Mysoft.Map.Utility.General.GetImportExcelTempFileName(); //excel临时名

        //    //流文件保存为Excel
        //    using (MemoryStream ms = tt.GetExcelStream())
        //    {
        //        //获取Excel文件流
        //        using (FileStream fs = new FileStream(excelPath, FileMode.Create))
        //        {
        //            using (BinaryWriter bw = new BinaryWriter(fs))
        //            {
        //                bw.Write(ms.ToArray());
        //            }
        //        }
        //    }

        //    //转换为下载路径
        //    string tmpRootDir = context.Server.MapPath(context.Request.ApplicationPath);
        //    string excelPath2 = excelPath.Replace(tmpRootDir, "");
        //    excelPath2 = excelPath2.Replace("\\", "/");

        //    //输出下载地址
        //    return JsonConvert.SerializeObject(excelPath2);
        //}
        
        /// <summary>
        /// 从HTML的Table导出为Excel文件
        /// </summary>
        /// <param name="excelFullName"></param>
        /// <returns></returns>
        [Action]
        public string ExportFromHtml(string excelFullName)
        {
            excelFullName = string.IsNullOrEmpty(excelFullName)
                ? context.Server.MapPath(context.Request.ApplicationPath) + "/tempfiles/" + DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(10000, 99999) + ".xls"
                : excelFullName;
            //导出请求数据
            List<List<ExcelCell>> excelDataList = JsonConvert.DeserializeObject<List<List<ExcelCell>>>(context.Request["ExportData"]);
            ExportExcelSetting settings = JsonConvert.DeserializeObject<ExportExcelSetting>(context.Request["ExcelSettings"])
                ?? new ExportExcelSetting();

            //导出数据表
            ExcelCreator.ExportToExcel(excelDataList, excelFullName, settings);

            //转换为下载路径
            string tmpRootDir = context.Server.MapPath(context.Request.ApplicationPath);
            string excelPath2 = excelFullName.Replace(tmpRootDir, "");
            excelPath2 = excelPath2.Replace("\\", "/");

            //输出下载地址
            return JsonConvert.SerializeObject(excelPath2);
        }

        /// <summary>
        /// 通用Form表单查询，在不创建实体对象的前提下，可将DataTable的第一行数据直接返回为JSON数据格式。
        /// 便于Form表单页面快速开发。
        /// </summary>
        /// <returns></returns>
        [Action]
        public string First()
        {
            CommandObject sql = JsonConvert.DeserializeObject<CommandObject>(context.Request["Command"]);
            Dictionary<string, object> dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(context.Request["Filters"]);
            List<SqlParameter> parameters = new List<SqlParameter>();
            foreach (KeyValuePair<string, object> kv in dict)
            {
                parameters.Add(new SqlParameter(kv.Key, kv.Value));
            }
            DataTable table = CPQuery.From(SqlFile.GetContent(sql.File), parameters.ToArray()).FillDataTable();
            string result = JsonConvert.SerializeObject(table);
            result = Regex.Replace(Regex.Replace(result, "^\\[", ""), "]$", "");    //Table会转换为数组形式的JSON，因此去除数组符号[]
            //return JsonConvert.SerializeObject(result);
            return string.IsNullOrEmpty(result) ? JsonConvert.SerializeObject(string.Empty) : result;
        }

        /// <summary>
        /// 默认保存方法
        /// </summary>
        /// <returns></returns>
        [Action]
        public string Save()
        {
            string fullClassName = context.Request["FullClassName"];
            string nmSpace = fullClassName.Substring(0, fullClassName.LastIndexOf('.'));
            BaseEntity entity = JsonConvert.DeserializeObject(context.Request["formData"],
                Assembly.Load(nmSpace).GetType(fullClassName),
                new JsonSerializerSettings()
                {
                    NullValueHandling = NullValueHandling.Ignore
                }) as BaseEntity;

            ValidationResult vr = DataValidator.Exec(entity);
            if (vr.Result == false)
            {
                //返回校验失败结果
                return JsonConvert.SerializeObject(new HttpResult() { Result = false, ErrorMessage = vr.ErrorMessage });
            }
            object id = new BaseDAL().SaveEntity(entity);
            return JsonConvert.SerializeObject(new HttpResult() { Result = true, KeyValue = id.ToString() });
        }

        /// <summary>
        /// 默认删除方法
        /// </summary>
        /// <returns></returns>
        [Action]
        public string Delete()
        {
            string id = context.Request["OID"];
            string classFullName = context.Request["FullClassName"];
            string nmSpace = classFullName.Substring(0, classFullName.LastIndexOf('.'));
            new BaseDAL().DeleteEntity(id, Assembly.Load(nmSpace).CreateInstance(classFullName, true));
            return JsonConvert.SerializeObject(new HttpResult() { Result = true });
        }
    }
}